#include "glsprites.h"
#include <QKeyEvent>
#include <QBitmap>
#include <Phonon>
#include <QMessageBox>

GLWidget::GLWidget() : QGLWidget()
{
    mouseLocked = false;

    for ( int i = 0; i < nSounds; i++ ) {
        audioOutput[i] = new Phonon::AudioOutput(Phonon::MusicCategory, this);
        mediaObject[i] = new Phonon::MediaObject(this);
        Phonon::createPath(mediaObject[i], audioOutput[i]);
    }

    mediaObject[0]->setCurrentSource(Phonon::MediaSource("res/TheImperialMarch.mp3"));
    mediaObject[1]->setCurrentSource(Phonon::MediaSource("res/SaberOn.wav"));
    mediaObject[2]->setCurrentSource(Phonon::MediaSource("res/SaberOff.wav"));
    mediaObject[3]->setCurrentSource(Phonon::MediaSource("res/breathe.wav"));
    audioOutput[3]->setVolume( 0.5 );
    mediaObject[3]->play();
    mediaObject[0]->play();


}

GLWidget::~GLWidget()
{
}

// GL inicijavimo metodas
void GLWidget::initializeGL()
{    
    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    texture[0] = bindTexture(QPixmap(QString(":/img/MAX0010.jpg")), GL_TEXTURE_2D);
    texture[1] = bindTexture(QPixmap(QString(":/img/all.PNG")), GL_TEXTURE_2D);
    texture[2] = bindTexture(QPixmap(QString(":/img/vader.png")), GL_TEXTURE_2D);

    glEnable(GL_TEXTURE_2D);
    glColor4f(1.0f,1.0f,1.0f,1.0f);
    glEnable(GL_BLEND);
    glEnable(GL_ALPHA_TEST);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glAlphaFunc(GL_GREATER,0.1f);

}

// GL lango dydžio keitimo metodas,
// w - naujas lango plotis,
// h - naujas lango aukštis,
void GLWidget::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,w,0,h,-100,100);
    glMatrixMode(GL_MODELVIEW);
    glClearColor(0.0f,0.0f,0.0f,1.0f);
}

// GL kadro piešimo metodas
void GLWidget::paintGL()
{    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

//    glColor3f(0.5f, 0.5f, 0.5f);
    glBindTexture(GL_TEXTURE_2D,texture[0]);
//    glRotatef( 45.0f, 0.0f, 0.0f, 1.0f );
    glBegin(GL_QUADS);
     glTexCoord2f(0.0f,0.0f); glVertex3i(  0, 0,-100);
     glTexCoord2f(0.0f,1.0f); glVertex3i(  0, 600,-100);
     glTexCoord2f(1.0f,1.0f); glVertex3i(800, 600,-100);
     glTexCoord2f(1.0f,0.0f); glVertex3i(800, 0,-100);
    glEnd();


    static float x = 360, y = 300;    // spraito koordinatės
    static int dir = 0;         // spraito pasisukimo pusė
    static int counter = 0;     // skaičiuojami kadrai

    float speed = 1.25f;

    if ( Kh[Qt::Key_Down] ) {
        dir = 0;
        y -= speed;
    } else if ( Kh[Qt::Key_Up] ) {
        dir = 2;
        y += speed;
    } else if ( Kh[Qt::Key_Left] ) {
        dir = 1;
        x -= speed;
    } else if ( Kh[Qt::Key_Right] ) {
        dir = 3;
        x += speed;
    } else {
        counter = 38;
    }

//    counter++;
//    int frame = (counter % 40)/10; // keičiasi tarp 0 ir 3 kas sekundę
//    frame = (( frame%2 == 1 )? dir : (4+2*dir+((frame>=2)?0:1)));   // randa kadrą pagal pasisukimo pusę ir
//
//    glLoadIdentity();
//    glBindTexture(GL_TEXTURE_2D, texture[1]);
//    glBegin(GL_QUADS);  // piešiamas žmogeliukas
//        glTexCoord2f( frame/16.0f, 0.0f ); glVertex3i( x+0, y+0, -100 );
//        glTexCoord2f( frame/16.0f, 1.0f ); glVertex3i( x+0, y+64, -100 );
//        glTexCoord2f( (frame+1)/16.0f, 1.0f ); glVertex3i( x+32, y+64, -100 );
//        glTexCoord2f( (frame+1)/16.0f, 0.0f ); glVertex3i( x+32, y+0, -100 );
//    glEnd();


    static int l = 0;
    if ( Kl.contains(Qt::Key_L) ) {

        if ( l == 0 ) {
            mediaObject[1]->seek(0);
            mediaObject[1]->play();
            l = 1;
        } else {
            l = 0;
            mediaObject[2]->seek(0);
            mediaObject[2]->play();
        }
    }

    counter++;
    int frame = (counter % 40)/10; // keičiasi tarp 0 ir 3 kas sekundę
    frame = (frame%2 == 1) ? 0 : ((frame==0) ? 1 : 2 );

    if ( Mh[Qt::MidButton] ) {
        x = Mx;
        y = 600-My;
    }
    if ( Ml.contains(Qt::LeftButton) ) {
        x = Mx;
        y = 600-My;
    }
    if ( Mh[Qt::RightButton] ) {
        x += Mdx;
        y -= Mdy;
    }

    glLoadIdentity();
    glBindTexture(GL_TEXTURE_2D, texture[2]);
    glBegin(GL_QUADS);  // piešiamas Vaderis
        glTexCoord2f( (frame+l*3)/8.0f, (7-dir)/8.0f ); glVertex3i( x+0, y+0, -100 );
        glTexCoord2f( (frame+l*3)/8.0f, (8-dir)/8.0f ); glVertex3i( x+0, y+64, -100 );
        glTexCoord2f( (frame+1+l*3)/8.0f, (8-dir)/8.0f ); glVertex3i( x+64, y+64, -100 );
        glTexCoord2f( (frame+1+l*3)/8.0f, (7-dir)/8.0f ); glVertex3i( x+64, y+0, -100 );
    glEnd();


    // spausdina tekstą
    QString lol = QString("Window size:" + QString::number(this->width()) + "x" + QString::number(this->height()));
    static QFont font = QFont("Verdana", 20, 0, 0 );    // teksto šifras
    glLoadIdentity();
    glColor3f(1.0f, 1.0f, 1.0f );
    this->renderText( 10, 50, lol, font );

}

// metodas pagrindinei žaidimo logikai apdoroti
// return - grąžina 0 sekmingo vykdymo metu, -1 programos baigimui
int GLWidget::doLogic()
{
    if ( Kh[Qt::Key_Escape] )   // Escape baigia progrmamą
        return -1;

    if ( mediaObject[3]->remainingTime() < 1 )
    {
        mediaObject[3]->seek(0);
        mediaObject[3]->play();
    }



    return 0;
}


// metodas priima mygtukų paspaudimo komandas ir jas sukelia į sąrašus
// e - QKeyEventas, informacija apie paspaustą/atspaustą mygtuką
// isPressed - ar mygtukas paspaustas
void GLWidget::handleKeys(QKeyEvent* e, bool isPressed)
{
    // mygtukų būsenos surašomos į hash lentelę
    if ( Kh.contains(e->key()) ) {   // hash table
        Kh[e->key()] = isPressed;
    } else {
        Kh.insert( e->key(), isPressed );
    }

    // visi paspausti mygtukai renkami į eilę, kad būtu apdoroti sekančio kadro metu
    if ( isPressed )
        Kq.enqueue( e->key() );
}

void GLWidget::mousePressEvent(QMouseEvent* e)
{
    Mh[e->button()] = true;
    Mq.enqueue( e->button() );
}

void GLWidget::mouseMoveEvent(QMouseEvent* e)
{
}
void GLWidget::mouseReleaseEvent(QMouseEvent* e)
{
    Mh[e->button()] = false;
}

// metodas tikrina pelės judėjimą, bei paruošia nuspaustų mygtukų eilę
void GLWidget::handleControls()
{
    static QPoint pos(QCursor::pos());
    static QPoint d;
    d = QCursor::pos() - pos;
    if ( mouseLocked )
        QCursor::setPos(500,400);   // "center" of the screen
    pos = QCursor::pos();
    Mdx = d.x();
    Mdy = d.y();

    QPoint p = this->mapFromGlobal(QCursor::pos());
    Mx = p.x();
    My = p.y();

    Ml.clear();
    while(!Mq.isEmpty())
        Ml.append(Mq.dequeue());

    Kl.clear();
    while (!Kq.isEmpty())
        Kl.append(Kq.dequeue());
}

// Metodas "užrakiną" pelę kad jos judėjimą gautu tik GL langas
void GLWidget::lockMouse()
{
    static QBitmap cur(16,16);
    cur.clear();
    QCursor::setPos(500,400);
    mouseLocked = true;
    this->grabMouse( QCursor(cur, cur, 0, 0) );
}

// metodas "atrakina" pelę
void GLWidget::unlockMouse()
{
    mouseLocked = false;
    this->releaseMouse();
}
